#include "Vector.h"
#include <math.h>

Vector::Vector()
{
	thisVector.x = 1.0f;
	thisVector.y = 1.0f;
	thisVector.z = 1.0f;
	coord g(thisVector.x,thisVector.y,thisVector.z);
	initialStart = coord(0,0,0);
	initialEnd = g;
	startVector = initialStart;
	endVector = initialEnd;
	
	this->X_Y_Z[0] = thisVector.x;
	this->X_Y_Z[1] = thisVector.y;
	this->X_Y_Z[2] = thisVector.z;
}

Vector::Vector (float x, float y, float z)
{
	thisVector.x = (GLfloat)x;
	thisVector.y = (GLfloat)y;
	thisVector.z = (GLfloat)z;
	coord g(thisVector.x,thisVector.y,thisVector.z);
	initialStart = coord(0,0,0);
	initialEnd = g;
	startVector = initialStart;
	endVector = initialEnd;
	
	this->X_Y_Z[0] = thisVector.x;
	this->X_Y_Z[1] = thisVector.y;
	this->X_Y_Z[2] = thisVector.z;
}

Vector::Vector(coord start, coord end)
{
	thisVector.x = end.x - start.x ;
	thisVector.y = end.y - start.y ;
	thisVector.z = end.z - start.z ;
	initialStart = start;
	initialEnd = end;
	startVector = start;
	endVector = end;


	this->X_Y_Z[0] = thisVector.x;
	this->X_Y_Z[1] = thisVector.y;
	this->X_Y_Z[2] = thisVector.z;

}

float Vector::returnLength()
{
	return sqrt((thisVector.x*thisVector.x) + (thisVector.y*thisVector.y) + (thisVector.z*thisVector.z));
}

void Vector::normalize()
{
	float length = this->returnLength();
	thisVector.x = thisVector.x/length;
	thisVector.y = thisVector.y/length;
	thisVector.z = thisVector.z/length;
}

void Vector::reset()
{
	startVector = initialStart;
	endVector = initialEnd;
}

void Vector::addVector(Vector * otherVector)
{
	thisVector.x += otherVector->thisVector.x;
	thisVector.y += otherVector->thisVector.y;
	thisVector.z += otherVector->thisVector.z;
}

void Vector::addVector(Vector  otherVector)
{
	thisVector.x += otherVector.thisVector.x;
	thisVector.y += otherVector.thisVector.y;
	thisVector.z += otherVector.thisVector.z;
}

void Vector::subtractVector(Vector * otherVector)
{
	thisVector.x -= otherVector->thisVector.x;
	thisVector.y -= otherVector->thisVector.y;
	thisVector.z -= otherVector->thisVector.z;
}

void Vector::subtractVector(Vector otherVector)
{
	thisVector.x -= otherVector.thisVector.x;
	thisVector.y -= otherVector.thisVector.y;
	thisVector.z -= otherVector.thisVector.z;
}

void Vector::multiplyVector(Matrix33 *mat)
{
	this->thisVector.x = (mat->matrix33[0][0] * this->thisVector.x) + (mat->matrix33[0][1] * this->thisVector.y) + (mat->matrix33[0][2] * this->thisVector.z);
	this->thisVector.y = (mat->matrix33[1][0] * this->thisVector.x) + (mat->matrix33[1][1] * this->thisVector.y) + (mat->matrix33[1][2] * this->thisVector.z);
	this->thisVector.z = (mat->matrix33[2][0] * this->thisVector.x) + (mat->matrix33[2][1] * this->thisVector.y) + (mat->matrix33[2][2] * this->thisVector.z);
}

void Vector::multiplyVector(Matrix33 mat)
{
	this->thisVector.x = (mat.matrix33[0][0] * this->thisVector.x) + (mat.matrix33[0][1] * this->thisVector.y) + (mat.matrix33[0][2] * this->thisVector.z);
	this->thisVector.y = (mat.matrix33[1][0] * this->thisVector.x) + (mat.matrix33[1][1] * this->thisVector.y) + (mat.matrix33[1][2] * this->thisVector.z);
	this->thisVector.z = (mat.matrix33[2][0] * this->thisVector.x) + (mat.matrix33[2][1] * this->thisVector.y) + (mat.matrix33[2][2] * this->thisVector.z);
}

void Vector::multiplyVector(Quaternion *rotationQuat)
{
	Quaternion *vector = new Quaternion(this);
	Quaternion *rotationQuat_conjugate = new Quaternion(rotationQuat->conjugate());
	Quaternion *vectorNew = new Quaternion(vector->multiply(rotationQuat_conjugate));
	Quaternion *result = new Quaternion(rotationQuat->multiply(vectorNew));
	thisVector.x = result->x;
	thisVector.y = result->y;
	thisVector.z = result->z;
}

void Vector::multiplyVector(Quaternion rotationQuat)
{
	Quaternion *vector = new Quaternion(this);
	Quaternion *rotationQuat_conjugate = new Quaternion(rotationQuat.conjugate());
	Quaternion *vectorNew = new Quaternion(vector->multiply(rotationQuat_conjugate));
	Quaternion *result = new Quaternion(rotationQuat.multiply(vectorNew));
	thisVector.x = result->x;
	thisVector.y = result->y;
	thisVector.z = result->z;
}

void Vector::multiplyVector(float scalar)
{
	thisVector.x *= scalar;
	thisVector.y *= scalar;
	thisVector.z *= scalar;
}

float Vector::dotProduct(Vector *otherVector)
{
	return ( (thisVector.x * otherVector->thisVector.x) +
			 (thisVector.y * otherVector->thisVector.y) +
			 (thisVector.z * otherVector->thisVector.z) );
}

void Vector::updateVector(Matrix33 * rotationMatrix, Vector * translationVector)
{
}


/*******************************************
*                                          *
*		OVERLOADED OPERATORS               *
*                                          *
*******************************************/
Vector Vector::operator+(Vector other)
{
	Vector newV = *this;
	newV.addVector(other);
	return newV;
}

Vector Vector::operator-(Vector other)
{
	Vector newV = *this;
	newV.subtractVector(other);
	return newV;
}

Vector Vector::operator*(Matrix33 other)
{
	Vector newV = *this;
	newV.multiplyVector(other);
	return newV;
}

Vector Vector::operator*(Quaternion other)
{
	Vector newV = *this;
	newV.multiplyVector(other);
	return newV;
}

Vector Vector::operator*(float scalar)
{
	Vector newV = *this;
	newV.multiplyVector(scalar);
	return newV;
}


Vector::~Vector()
{

}